package com.feishi.core.analytic.packing.contentpacking;

import com.feishi.core.util.common.ByteUtil;
import com.feishi.core.analytic.body.AnalyticBody;
import com.feishi.core.analytic.element.AnalyticContentMapElement;
import com.feishi.core.analytic.packing.AnalyticDataPacking;
import com.feishi.core.analytic.packing.debuild.DeBuildSession;
import com.feishi.core.analytic.packing.encode.EncodeParam;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by caixq on 5/9 009.
 */
public class AnalyticContentMapPacking extends AnalyticContentPacking implements ContentLengthPacking {
    private AnalyticContentMapElement contentElement;
    Map<String,Object> typeMap=new HashMap<>();
    private byte[] encode;
    private byte[] length;
    private AnalyticDataPacking contentDataPacking;
    private byte[] encodeContent;
    private EncodeParam encodeParam;

    public void setContentDataPacking(AnalyticDataPacking contentDataPacking) {
        this.contentDataPacking = contentDataPacking;
    }

    public AnalyticContentMapPacking(AnalyticContentMapElement contentElement) {
        this.contentElement=contentElement;
    }

    public AnalyticContentMapElement getContentElement() {
        return contentElement;
    }

    public void setContentElement(AnalyticContentMapElement contentElement) {
        this.contentElement = contentElement;
    }

    public void setType(String typeName, Object obj){
        byte[] type = contentElement.getContentType(typeName).getBytes(obj);
        typeMap.put(typeName,type);
    }
    public void setType(String typeName, byte[] type){
        typeMap.put(typeName,type);
    }
    public void setEncode(Object obj){
        this.encode=contentElement.getContentEncode().getBytes(obj);
    }
    public AnalyticDataPacking getContentDataPacking() {
        if(this.contentDataPacking!=null){
            return contentDataPacking;
        }
        AnalyticBody body =contentElement.getBody(typeMap);
        this.contentDataPacking = body.analyticBuildPacking().analyticDataPacking();

        return contentDataPacking;
    }

    public AnalyticDataPacking getNewContentDataPacking() {
        AnalyticBody body =contentElement.getBody(typeMap);
        this.contentDataPacking = body.analyticBuildPacking().analyticDataPacking();
        return contentDataPacking;
    }
    public void initData(){
        if(this.content==null){
            this.forceInitData();
        }
        if(this.contentElement.getContentLength()!=null){
            this.length=this.contentElement.getContentLength().getBytes(getContent().length);
        }
    }

    private void forceInitData() {
        if(contentDataPacking!=null){
            contentDataPacking.addSession(buildSession);
            this.content=contentDataPacking.build();
        }else{
            this.content=new byte[0];
        }
        if(this.contentElement.getContentLength()!=null){
            this.length=this.contentElement.getContentLength().getBytes(getContent().length);
        }


    }

    public byte[] getType(String name) {
        return (byte[]) typeMap.get(name);
    }
    public Object getTypeValue(String name) {
        return this.getContentElement().getContentType(name).getValue(getType(name));
    }
    public Object getEncodeValue() {
        return this.getContentElement().getContentEncode().getValue(this.encode);
    }


    public byte[] getEncode() {
        return encode;
    }

    public void setEncode(byte[] encode) {
        this.encode = encode;
    }

    public byte[] getLength() {
        return length;
    }

    public void setLength(byte[] length) {
        this.length = length;
    }

    public byte[] getContent() {
        if(this.encodeContent==null){

            if(this.getContentElement().getContentEncode()!=null){
                this.encodeContent=this.getContentElement().getContentEncode().encode(content,encode,this.encodeParam);
            }else{
                this.encodeContent=content;
            }
        }
        return encodeContent;
    }


    public void setContent(byte[] content) {
        this.encodeContent=content;
        if(this.getContentElement().getContentEncode()!=null){
            this.content=this.getContentElement().getContentEncode().decode(encodeContent,encode,this.encodeParam);
        }else{
            this.content = content;
        }
    }

    public boolean isRepeatable() {
        return this.contentElement.isRepeatable();
    }

    public int getContentLength() {
        if(length!=null){
            return ByteUtil.toInt(length);
        }
        getContentDataPacking();
        if(this.contentDataPacking.isLengthStatic()){
            return this.contentDataPacking.getStaticLength();
        }
        return 0;
    }

    @Override
    public void debuildContent(byte[] bytes) {
        getContentDataPacking();
        this.contentDataPacking.clear();
        contentDataPacking.buildSession=contentDataPacking.deBuildSession= (DeBuildSession) buildSession;
        this.contentDataPacking.deBuild(bytes);
        if(this.content==null){
            this.content=this.contentDataPacking.build();
        }
    }


    public void debuildContent() {
        debuildContent(this.content);
    }

    public void setEncodeParam(EncodeParam encodeParam) {
        this.encodeParam = encodeParam;
    }
}
